# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
import base64, random, codecs, requests, time, hashlib, datetime
from fake_useragent import UserAgent
from http.cookiejar import LWPCookieJar


class WYY:
    ua = UserAgent()

    SearchKeyWord = '{"hlpretag":" <span class =\\\"s-fc7\\\">", "hlposttag":"</span>", "s": "%s", "type": "%s", "offset": "%s", "total": "true", "limit": "30", "csrf_token": ""}'
    Comments = '{"rid":"R_SO_4_%s","offset":"%s","total":"true","limit":"20","csrf_token":""}'
    SongUrl = '{"ids":"[%s]","level":"standard","encodeType":"aac","csrf_token":""}'
    LoginParam = '{"phone":"%s","password":"%s","rememberLogin":"true","checkToken":"","csrf_token": ""}'

    def __init__(self):
        self.arg2 = "010001"
        self.arg3 = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
        self.arg4 = "0CoJUm6Qyw8W8jud"
        self.session = requests.Session()
        self.session.headers = {
            "Referer": "https://music.163.com/",
            "User-Agent": self.ua.random
        }
        self.session.cookies = LWPCookieJar(filename="./cookie.txt")
        self.__get_random_str()

    def __AES_encrypt(self, text, key):
        '''
        获取到加密后的数据
        :param text: 首先CBC加密方法，text必须位16位数据
        :param key: 加密的key
        :return: 加密后的字符串
        '''
        iv = "0102030405060708"
        pad = 16 - len(text) % 16
        if isinstance(text, str):
            text = text + pad * chr(pad)
        else:
            text = str(text, encoding="utf-8") + pad * chr(pad)
        aes = AES.new(key=bytes(key, encoding="utf-8"), mode=2, iv=bytes(iv, encoding="utf-8"))
        res = aes.encrypt(bytes(text, encoding="utf-8"))
        res = base64.b64encode(res).decode("utf-8")
        return res

    def __get_encText(self, args1):
        encText = self.__AES_encrypt(args1, self.arg4)
        encText = self.__AES_encrypt(encText, self.random_16_str)
        return encText

    def __get_encSecKey(self):
        '''通过查看js代码，获取encSecKey'''
        text = self.random_16_str[::-1]
        rs = int(codecs.encode(text.encode('utf-8'), 'hex_codec'), 16) ** int(self.arg2, 16) % int(self.arg3, 16)
        return format(rs, 'x').zfill(256)

    def __get_random_str(self):
        '''这是16位的随机字符串'''
        str_set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        random_str = ""
        for i in range(16):
            index = random.randint(0, len(str_set) - 1)
            random_str += str_set[index]
        self.random_16_str = random_str

    def __getFormData(self, args1):
        '''获取到提交的数据'''
        data = {"params": self.__get_encText(args1), "encSecKey": self.__get_encSecKey()}
        return data

    def __timestamp_to_timeformate(self, timestamp):
        '''将时间戳转为某种格式的时间'''
        time_local = time.localtime(timestamp / 1000)
        dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local)
        return dt

    def downloadSong(self, songId):
        '''获取到歌曲的下载的地址就好了。如果想要下载可以单独再写一个方法去下载音乐'''
        print("开始爬取歌曲mp3地址....")
        arg_mp3 = self.SongUrl % songId
        api = "https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token="
        headers = self.session.headers.copy()
        formdata = self.__getFormData(arg_mp3)
        response = self.session.post(url=api, data=formdata, headers=headers)
        print("歌曲的下载地址为>>:", response.json()["data"][0]["url"])

    def song_comment(self, songId):
        '''获取到歌曲评论信息，我只是将结果print出来，如果保存的话，可以单独写一个保存的方法'''
        print("开始爬取歌曲评论信息....")
        # 第一页为0，第二页为20，第三页为40  第四页为60  第五页为80
        offset = 0
        n = 1
        api = "https://music.163.com/weapi/v1/resource/comments/R_SO_4_{}?csrf_token=".format(songId)
        headers = self.session.headers.copy()
        arg_comment = self.Comments % (songId, offset)
        while True:
            formdata = self.__getFormData(arg_comment)
            response = self.session.post(url=api, headers=headers, data=formdata)
            comment_list = response.json().get("comments")
            if not comment_list:
                break
            for dic in comment_list:
                try:
                    print("用户: {}".format(dic["user"]["nickname"]))
                    print("评论时间： {} ".format(self.__timestamp_to_timeformate(dic.get("time"))))
                    print("评论内容： {} ".format(dic.get("content")))
                    print()
                except UnicodeEncodeError:
                    pass
            print("第 {} 页评论".format(n))
            offset += 20
            n += 1
            arg_comment = self.Comments % (songId, offset)
            time.sleep(3)

    def login(self, username: str = None, password: str = None):
        '''网易云登录'''
        api = "https://music.163.com/weapi/login/cellphone?csrf_token="
        headers = {}
        headers["content-type"] = "application/x-www-form-urlencoded"
        headers["user-agent"] = self.ua.random
        headers["referer"] = "https://music.163.com/"
        if not username:
            username = input("输入你的电话>>:").strip()
        else:
            username = username.strip()
        if not password:
            password = input("输入你的密码>>:").strip()
        else:
            password = password.strip()
        arg_login = self.LoginParam % (
            username, hashlib.md5(bytes(password, encoding="utf-8")).hexdigest())
        formdata = self.__getFormData(arg_login)
        response = self.session.post(url=api, headers=headers, data=formdata)
        results = response.json()

        if results["code"] == 200:
            self.session.cookies.save()
            print("登录成功")
        else:
            print(results["msg"])

    def search_KeyWord(self, kw, offset=0, keyword_dict_key="单曲"):
        '''通过搜索关键字'''
        '''
        歌手:100
        单曲:1
        专辑:10
        视频:1014
        歌词:1006
        歌单:1000
        主播电台:1009
        用户:1002
        '''
        if not hasattr(self, "keyword_dict"):
            self.keyword_dict = {
                "歌手": 100,
                "单曲": 1,
                "专辑": 10,
                "视频": 1014,
                "歌词": 1006,
                "歌单": 1000,
                "主播电台": 1009,
                "用户": 1002,
            }
        keyword_dict_value = self.keyword_dict.get(keyword_dict_key, 1)
        arg_keyword = self.SearchKeyWord % (kw, keyword_dict_value, offset)
        api = "https://music.163.com/weapi/cloudsearch/get/web?csrf_token="
        headers = self.session.headers.copy()
        formdata = self.__getFormData(bytes(arg_keyword, encoding="utf-8"))
        response = self.session.post(url=api, data=formdata, headers=headers).json()
        if response.get("code") != 200:
            return
        result = response.get("result")

        print(result)

    def text(self):
        '''测试方式'''
        pass


if __name__ == '__main__':
    wyy = WYY()
    # wyy.song_comment("444267215")
    # wyy.search_KeyWord("喜欢的是你的微笑",keyword_dict_key="歌词")
    # wyy.downloadSong("444267215")
    # wyy.login("18716758271", "123456")
